//-----------------------------------------------------------------------------
// Copyright (c) 2011 David Waby
// Initially created on 31/10/2011
//-----------------------------------------------------------------------------

#include "Global.h"
#include "Tile.h"
#include "TileAttributePortal.h"
#include "TileAttributeChest.h"

//-----------------------------------------------------------------------------
Tile::Tile(int const x, int const y)
:	m_position(x, y)
,	m_flags(0)
,	m_attribute(NULL)
{
}

//-----------------------------------------------------------------------------
Tile::~Tile()
{
	delete m_attribute;
}

		
//-----------------------------------------------------------------------------
void Tile::SetAttribute(TileAttributes::Enum const i_attribute, bool const i_set)
{
	if (i_set)
	{
		BITFLAG_SET(m_flags, i_attribute);
		CreateAttribute(i_attribute);
	}
	else
	{
		BITFLAG_CLEAR(m_flags, i_attribute);
		DeleteAttribute(i_attribute);
	}
}

//-----------------------------------------------------------------------------
bool Tile::HasAttribute(TileAttributes::Enum const i_attribute) const
{
	return BITFLAG_ISSET(m_flags, i_attribute);
}

//-----------------------------------------------------------------------------
TileAttribute * Tile::GetAttribute() const
{
	return m_attribute;
}

//-----------------------------------------------------------------------------
void Tile::CreateAttribute(TileAttributes::Enum const i_attribute)
{
	switch (i_attribute)
	{
		case TileAttributes::Portal:
		{
			m_attribute = new TileAttributePortal();
			break;
		}
		case TileAttributes::Chest:
		{
			m_attribute = new TileAttributeChest();
			break;
		}
		default:
			break;
	};
}

//-----------------------------------------------------------------------------
void Tile::DeleteAttribute(TileAttributes::Enum const i_attribute)
{
	if ((m_attribute) && (m_attribute->GetAttributeType() == i_attribute))
	{
		delete m_attribute;
		m_attribute = NULL;
	}
}

//-----------------------------------------------------------------------------
void Tile::EnterTile()
{
	if (m_attribute)
	{
		m_attribute->OnEnter();
	}
}

//-----------------------------------------------------------------------------
void Tile::UseTile()
{
	if (m_attribute)
	{
		m_attribute->Use();
	}
}

//-----------------------------------------------------------------------------
void Tile::ExitTile()
{
	if (m_attribute)
	{
		m_attribute->OnExit();
	}
}

//-----------------------------------------------------------------------------
void Tile::Serialise(Json::Value * o_root) const
{
}

//-----------------------------------------------------------------------------
void Tile::Deserialise(Json::Value const * i_root)
{
	Json::Value element = (*i_root)["loc"];
	m_position.Deserialise(&element);

	// Loop through all of the attributes
	element = (*i_root)["attr"];
	for (Json::ArrayIndex counter = 0; counter < element.size(); ++counter)
	{
		// Check if the tile can be walked on
		Json::Value attribute = element[counter]["walk"];
		if (!attribute.empty())
		{
			SetAttribute(Tile::TileAttributes::Walkable, true);
		}

		// Check if the tile has a portal
		attribute = element[counter]["portal"];
		if (!attribute.empty())
		{
			SetAttribute(Tile::TileAttributes::Portal, true);

			// Get the created portal
			TileAttributePortal * portalAttribute = static_cast<TileAttributePortal*>(GetAttribute());
			portalAttribute->Deserialise(&attribute);

			continue;
		}

		// Check if the tile is a chest tile
		attribute = element[counter]["chest"];
		if (!attribute.empty())
		{
			SetAttribute(Tile::TileAttributes::Chest, true);

			continue;
		}
	}
}